Disable HPET broadcast mode on kexec.
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 1 Oct 2009 11:25:36 +0000 (12:25 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 1 Oct 2009 11:25:36 +0000 (12:25 +0100)
Without this the new kernel cannot receive timer interrupts from the
legacy sources. Hangs are observed in the second kernel's
"check_timer()" routing or at "Checking 'hlt' instruction."

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
xen/arch/x86/crash.c
xen/arch/x86/hpet.c

index 009ae9ab7ee5a4bbb3483f43670c357242e78d4c..1c90b6eca2dc22e51c455848062f06997d27ee1e 100644 (file)
@@ -25,6 +25,7 @@
 #include <public/xen.h>
 #include <asm/shared.h>
 #include <asm/hvm/support.h>
+#include <asm/hpet.h>
 
 static atomic_t waiting_for_crash_ipi;
 static unsigned int crashing_cpu;
@@ -83,6 +84,9 @@ void machine_crash_shutdown(void)
 
     nmi_shootdown_cpus();
 
+    if ( hpet_broadcast_is_available() )
+        hpet_disable_legacy_broadcast();
+
     disable_IO_APIC();
 
     hvm_cpu_down();
index 2136169f40eb4000c2b13f2cb4ab82eebcaf4fe7..3a560f11fc97d1c33b2362eb88bf5c1cfd83e472 100644 (file)
@@ -604,8 +604,9 @@ void hpet_broadcast_init(void)
 void hpet_disable_legacy_broadcast(void)
 {
     u32 cfg;
+    unsigned long flags;
 
-    spin_lock_irq(&legacy_hpet_event.lock);
+    spin_lock_irqsave(&legacy_hpet_event.lock, flags);
 
     legacy_hpet_event.flags |= HPET_EVT_DISABLE;
 
@@ -619,7 +620,7 @@ void hpet_disable_legacy_broadcast(void)
     cfg &= ~HPET_CFG_LEGACY;
     hpet_write32(cfg, HPET_CFG);
 
-    spin_unlock_irq(&legacy_hpet_event.lock);
+    spin_unlock_irqrestore(&legacy_hpet_event.lock, flags);
 
     smp_send_event_check_mask(&cpu_online_map);
 }